package com.bestcem.xm.ticket.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.lang.Validator;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.domain.message.RespondentSeq;
import com.bestcem.xm.common.core.domain.message.SampleCopyMessage;
import com.bestcem.xm.ticket.cache.client.CacheProjectClient;
import com.bestcem.xm.ticket.cache.dto.SurveyProjectDTO;
import com.bestcem.xm.ticket.dao.*;
import com.bestcem.xm.ticket.entity.mongo.*;
import com.bestcem.xm.ticket.enums.*;
import com.bestcem.xm.ticket.grpc.client.*;
import com.bestcem.xm.ticket.grpc.client.dto.survey.ColumnDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.GroupDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.IdMapNodeDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.SmtpDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.UserDTO;
import com.bestcem.xm.ticket.mq.send.biz.TicketMessageSendService;
import com.bestcem.xm.ticket.service.TicketCopySample;
import com.bestcem.xm.ticket.util.TicketUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author gy.liu
 * @version 1.0
 * @date 2021/8/16 16:18
 **/
@Slf4j
@Service
public class TicketCopySampleImpl implements TicketCopySample {

    private static final String TICKET_COPY_SAMPLE = "ticket.ids";

    public static Map<String, String> rpcModelIdMap = new HashMap<>();

    private Map<String, String> seqMap = new HashMap<>();

    private List<IdMapNodeDTO> idMapNodeDTOS4;

    private List<IdMapNodeDTO> idMapNodeDTOS;

    @Resource
    private TicketConfigDao ticketConfigDao;
    @Resource
    private TicketDao ticketDao;
    @Resource
    private TicketNotifyConfigDao ticketNotifyConfigDao;
    @Resource
    private TicketFlowDao ticketFlowDao;
    @Resource
    private TicketRuleDao ticketRuleDao;
    @Resource
    private TemplateDao templateDao;
    @Resource
    private TicketRecordDao ticketRecordDao;
    @Resource
    private AlertRecordDao alertRecordDao;
    @Resource
    private NotificationDao notificationDao;
    @Resource
    private TicketNotifySettingDao ticketNotifySettingDao;
    @Resource
    private TicketUserGrpcService ticketUserGrpcService;
    @Resource
    private TicketQdesGrpcService ticketQdesGrpcService;
    @Resource
    private TicketSurveyGrpcService ticketSurveyGrpcService;
    @Resource
    private TicketBaseSurveyGrpcService ticketBaseSurveyGrpcService;
    @Resource
    private TicketBaseUserGrpcService ticketBaseUserGrpcService;
    //    @Resource
//    private RabbitMessageSender rabbitMessageSender;
    @Resource
    private TicketUtil ticketUtil;

    //@Resource
    //private TicketMqProductUtil ticketMqProductUtil;

    @Autowired
    private TicketMessageSendService ticketMessageSendService;

    @Resource
    private CacheProjectClient cacheProjectClient;
    @Resource
    private TicketBaseQdesGrpcService ticketBaseQdesGrpcService;

    /**
     * 拷贝simple账号中的配置
     *
     * @param copyMessage
     * @author gy.liu
     * @date 2021/8/16
     */
    @Override
    public Map<String, String> ticketCopySample(SampleCopyMessage copyMessage) {
        String oldOrgId = "", newOrgId = "";
        List<RespondentSeq> seqList = new ArrayList<>();
        Boolean sample = false;
        if (!Objects.isNull(copyMessage)) {
            oldOrgId = copyMessage.getOrgSrcId();
            newOrgId = copyMessage.getOrgDstId();
            seqList = copyMessage.getSeqList();
        }
        if (StringUtils.isEmpty(oldOrgId) || StringUtils.isEmpty(newOrgId)) {
            if (log.isInfoEnabled()) {
                log.info("[Ticket] CopySample getModelIdMap start {}=>{}", oldOrgId, newOrgId);
            }
            return null;
        }

        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample getModelIdMap seqList {},isSample {}", JSONObject.toJSONString(seqList), copyMessage.getIsSample());
        }

        this.seqMap =
                seqList.stream().collect(Collectors.toMap(RespondentSeq::getSrcSeq, RespondentSeq::getDstSeq, (var1, var2) -> var2));


        if ("true".equals(copyMessage.getIsSample())) {
            sample = true;
            if (log.isInfoEnabled()) {
                log.info("[Ticket] ticketCopySample,sample={}", true);
            }
        } else if (copyMessage.getIsSample()) {
            sample = true;
            if (log.isInfoEnabled()) {
                log.info("[Ticket] ticketCopySample,sample2={}", true);
            }
        } else {
            sample = false;
            if (log.isInfoEnabled()) {
                log.info("[Ticket] ticketCopySample,sample1={}", false);
            }
        }

        Map<String, String> ticketIdMap = new HashMap<>();

        // 1.获取模型id
        getModelIdMap(oldOrgId, newOrgId);

        // 2.复制 示例 工单配置及对应的工单
        copy(oldOrgId, newOrgId, ticketIdMap, sample);

        return ticketIdMap;

    }

    /**
     * 获取模型id
     *
     * @param oldOrgId 行业sample租户id
     * @param newOrgId 目标租户id
     * @author gy.liu
     * @date 2021/8/16
     */
    private void getModelIdMap(String oldOrgId, String newOrgId) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample getModelIdMap start {}=>{}", oldOrgId, newOrgId);
        }

        // grpc获取用户idmap
        List<IdMapNodeDTO> idMapNodeDTOS = ticketUserGrpcService.getUserMapBySrcIdAndDstId(oldOrgId, newOrgId);
        if (log.isInfoEnabled()) {
            log.info("[ticket] getUserMapBySrcIdAndDstId：param={}", JSONObject.toJSONString(idMapNodeDTOS));
        }
        this.idMapNodeDTOS = idMapNodeDTOS;
        idMapCovert(idMapNodeDTOS, rpcModelIdMap);

        // grpc获取角色idmap
        List<IdMapNodeDTO> idMapNodeDTOS1 = ticketUserGrpcService.getRoleMapBySrcIdAndDstId(oldOrgId, newOrgId);
        if (log.isInfoEnabled()) {
            log.info("[ticket] getRoleMapBySrcIdAndDstId：param={}", JSONObject.toJSONString(idMapNodeDTOS1));
        }
        idMapCovert(idMapNodeDTOS1, rpcModelIdMap);

        // grpc获取组织idmap
        List<IdMapNodeDTO> idMapNodeDTOS2 = ticketUserGrpcService.getGroupMapBySrcIdAndDstId(oldOrgId, newOrgId);
        if (log.isInfoEnabled()) {
            log.info("[ticket] getGroupMapBySrcIdAndDstId：param={}", JSONObject.toJSONString(idMapNodeDTOS2));
        }
        idMapCovert(idMapNodeDTOS2, rpcModelIdMap);

        // grpc获取层级idmap
        List<IdMapNodeDTO> idMapNodeDTOS3 = ticketUserGrpcService.getGroupLevelMapBySrcIdAndDstId(oldOrgId, newOrgId);
        if (log.isInfoEnabled()) {
            log.info("[ticket] getGroupLevelMapBySrcIdAndDstId：param={}", JSONObject.toJSONString(idMapNodeDTOS3));
        }
        idMapCovert(idMapNodeDTOS3, rpcModelIdMap);

        // grpc获取项目idmap
        List<IdMapNodeDTO> idMapNodeDTOS4 = ticketQdesGrpcService.getProjectMapBySrcIdAndDstId(oldOrgId, newOrgId);
        if (log.isInfoEnabled()) {
            log.info("[ticket] getProjectMapBySrcIdAndDstId：param={}", JSONObject.toJSONString(idMapNodeDTOS4));
        }
        this.idMapNodeDTOS4 = idMapNodeDTOS4;

        idMapCovert(idMapNodeDTOS4, rpcModelIdMap);

        // grpc获取规则idmap
        getRuleMap(oldOrgId, newOrgId, rpcModelIdMap);

        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample getModelIdMap end {}=>{}", oldOrgId, newOrgId);
        }
    }

    /**
     * IdMapNodeDTO对象转换为map
     *
     * @param idMapNodeDTOS
     * @return Map<String, String>
     * @author gy.liu
     * @date 2021/9/1
     */
    public Map<String, String> idMapCovert(List<IdMapNodeDTO> idMapNodeDTOS, Map<String, String> rpcModelIdMap) {
        if (CollectionUtils.isEmpty(idMapNodeDTOS)) {
            log.error("[Ticket] 复制样类grpc调用失败");
        }

        for (IdMapNodeDTO idMapNodeDTO : idMapNodeDTOS) {
            if (StringUtils.isNotEmpty(idMapNodeDTO.getOldId()) && StringUtils.isNotEmpty(idMapNodeDTO.getNewId())) {
                rpcModelIdMap.put(idMapNodeDTO.getOldId(), idMapNodeDTO.getNewId());
            }
        }
        return rpcModelIdMap;
    }

    /**
     * 查询预警规则idmap
     *
     * @param oldOrgId 行业sample租户id
     * @param newOrgId 目标租户id
     * @return Map<String, String>
     * @author gy.liu
     * @date 2021/9/1
     */
    public Map<String, String> getRuleMap(String oldOrgId, String newOrgId, Map<String, String> rpcModelIdMap) {
        TicketRule ticketRule = ticketRuleDao.findById(oldOrgId);
        TicketRule ticketRuleNew = ticketRuleDao.findById(newOrgId);
        if (Objects.nonNull(ticketRule) && Objects.nonNull(ticketRuleNew)) {
            if (StringUtils.isNotEmpty(ticketRule.getId()) && StringUtils.isNotEmpty(ticketRuleNew.getId())) {
                rpcModelIdMap.put(ticketRule.getId(), ticketRuleNew.getId());
            }
        }
        return rpcModelIdMap;
    }

    /**
     * 复制样类工单
     *
     * @param oldOrgId 行业sample租户id
     * @param newOrgId 目标租户id
     * @author gy.liu
     * @date 2021/8/16
     */
    private Map<String, String> copy(String oldOrgId, String newOrgId, Map<String, String> ticketIdMap, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample copy start {}=>{}=>{}", oldOrgId, newOrgId, isSample);
        }

        // 根据组织id查询工单配置列表
        List<TicketConfig> ticketConfigList = ticketConfigDao.listByOrgIdEnable(oldOrgId);
        if (Objects.nonNull(ticketConfigList)) {
            if (log.isInfoEnabled()) {
                log.info("[ticket] 复制sample配置列表：param={}", JSONObject.toJSONString(ticketConfigList));
            }
            // 4.复制工单通知
            if (!CollectionUtils.isEmpty(idMapNodeDTOS4)) {
                for (IdMapNodeDTO idMapNodeDTO : idMapNodeDTOS4) {
                    if (Objects.nonNull(idMapNodeDTO)) {
                        if (!CollectionUtils.isEmpty(idMapNodeDTOS)) {
                            IdMapNodeDTO idMapNodeDTO1 = idMapNodeDTOS.get(0);
                            if (Objects.nonNull(idMapNodeDTO1)) {
                                if (log.isInfoEnabled()) {
                                    log.info("[ticket] 复制sample配置copy：surveyNew{},surveyOld{},userId{}", idMapNodeDTO.getNewId(), idMapNodeDTO.getOldId(), idMapNodeDTO1.getNewId());
                                }
                                copyNotification(idMapNodeDTO, newOrgId, idMapNodeDTO1.getNewId(), isSample);
                            }
                        }
                    }
                }
            }
            // 遍历工单配置列表
            for (TicketConfig ticketConfig : ticketConfigList) {
                // 问卷状态为删除状态的，不拷贝
                /*if (StringUtils.isNotEmpty(ticketConfig.getSurveyId())) {
                    if (!rpcModelIdMap.containsKey(ticketConfig.getSurveyId())) {
                        continue;
                    }
                }*/
                // 复制sample
                try {
                    if (log.isInfoEnabled()) {
                        log.info("[ticket] 复制sample开始：param={}", ticketConfig.getId());
                    }
                    copySample(ticketConfig, newOrgId, ticketIdMap, isSample);
                    if (log.isInfoEnabled()) {
                        log.info("[ticket] 复制sample结束：param={}", ticketConfig.getId());
                    }
                } catch (Exception e) {
                    log.error("[Ticket] copySample failed ", e);
                }
            }

            // 复制通知配置
            copyNotifySetting(oldOrgId, newOrgId, isSample);

        }

        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample copy end {}=>{}", oldOrgId, newOrgId);
        }
        return ticketIdMap;
    }

    /**
     * 复制sample
     * 拷贝工单配置, 保存后获得新的工单配置id,然后替换其他模型中的工单配置id
     * 更新工单模板,更新工单通知,更新工单流程
     * 更新工单(工单模型中有工单配置id),更新工单的时候, 更新工单记录
     *
     * @param ticketConfigNew 工单配置
     * @param newOrgId        目标租户id
     * @param ticketIdMap     工单id映射缓存
     * @author gy.liu
     * @date 2021/8/16
     */
    private Boolean copySample(TicketConfig ticketConfigNew, String newOrgId, Map<String, String> ticketIdMap, Boolean isSample) {

        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample copySample start {}=>{}", newOrgId, ticketConfigNew);
        }

        // 1.旧的工单配置转Map构造新的工单配置map
        String configId = ticketConfigNew.getId();
        String surveyId = ticketConfigNew.getSurveyId();

        // 2.替换rpc字段
        String[] rpcFields = {"userId", "surveyId", "alertId", "alertRuleIds"};
        String surveyId1 = rpcModelIdMap.get(ticketConfigNew.getSurveyId());
        String userId = rpcModelIdMap.get(ticketConfigNew.getUserId());
        if (StringUtils.isNotEmpty(surveyId1)) {
            ticketConfigNew.setSurveyId(surveyId1);
        }
        ticketConfigNew.setOrgId(newOrgId);
        ticketConfigNew.setUserId(userId);
        ticketConfigNew.setId(ObjectId.next());
        // 3.根据新的工单map构造新的工单对象
        ticketConfigDao.saveTicketConfig(ticketConfigNew);
        // ticketConfigNew的id是否新的

        // 5.复制工单通知配置
        copyNotifyConfig(ticketConfigNew, isSample);

        // 6.复制工单流程和工单
        copyTicketFlow(ticketConfigNew, configId, isSample);

        // 7.复制工单规则
        String existTicketRuleId = "";
        if (Objects.nonNull(ticketConfigNew.getTicketRuleId())) {
            copyTicketRule(ticketConfigNew.getTicketRuleId(), ticketConfigNew, existTicketRuleId, isSample);
        }

        // 8.复制状态规则
        if (Objects.nonNull(ticketConfigNew.getTicketNotifyConfigIds())) {
            copyStatusRuleList(ticketConfigNew.getTicketRuleId(), ticketConfigNew, isSample);
        }

        // 9.复制工单详情字段
        copyTicketDetailFields(ticketConfigNew);

        // 复制模板
        if (log.isInfoEnabled()) {
            log.info("[ticket] 复制工单模板start：param={}", configId);
        }
        TicketTemplateV2 template = copyTicketTemplate(ticketConfigNew, configId, isSample);
        if (log.isInfoEnabled()) {
            log.info("[ticket] 复制工单模板end：param={}", configId);
        }

        // 10.保存工单(包含保存工单记录,保存最新的流程信息)
        copyTicket(ticketConfigNew, configId, ticketIdMap, template, isSample);

 /*       // 11.保存记录
        copyRecord(ticketConfigNew, surveyId);*/

        // 12.更新工单配置
        if (isSample) {
            ticketConfigNew.setSample(true);
        }
        ticketConfigDao.updateTicketConfig(ticketConfigNew.getId(), ticketConfigNew);

        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample copySample end {}=>{}", newOrgId, ticketConfigNew);
        }

        return true;
    }

    /**
     * 复制记录
     *
     * @param ticketConfigNew
     * @param recordId
     * @return void
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/19
     */
    private String copyRecord(TicketConfig ticketConfigNew, String recordId, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[ticket] 复制记录开始：param={}", ticketConfigNew.getId());
        }
        Record record = alertRecordDao.findById(recordId);
        if (Objects.isNull(record)) {
            log.error("[ticket] 复制记录开始：records不存在");
            return null;
        }
        if (Objects.nonNull(record)) {
            record.setOrgId(ticketConfigNew.getOrgId());
            // 替换答卷编号和问卷id
            String qprojectID = "";
            if (!StringUtils.isEmpty(record.getQProjectId())) {
                qprojectID = rpcModelIdMap.get(record.getQProjectId());
            }
            String rspdSeq = "";
            if (!Objects.isNull(record.getRspdSeq())) {
                log.info("[ticket] 复制记录替换rspdSeq begin:{}", record.getRspdSeq());
                if (seqMap.containsKey(String.valueOf(record.getRspdSeq()))) {
                    rspdSeq = seqMap.get(String.valueOf(record.getRspdSeq()));
                    log.info("[ticket] 复制记录替换rspdSeq:{}", rspdSeq);
                    if (StringUtils.isNotEmpty(rspdSeq) && StringUtils.isNumeric(rspdSeq)) {
                        record.setRspdSeq(Long.valueOf(rspdSeq));
                    }
                }
            }
            if (isSample) {
                record.setSample(true);
            }
            record.setQProjectId(qprojectID);
            record.setId(ObjectId.next());
            if (log.isInfoEnabled()) {
                log.info("[ticket] 复制记录结束：param={}", record);
            }
            return alertRecordDao.saveTicketRecord(record).getId();
        }
        return null;
    }

    /**
     * 复制通知配置
     *
     * @param oldOrgId 行业sample租户id
     * @param newOrgId 目标租户id
     * @author gy.liu
     * @date 2021/8/16
     */
    private void copyNotifySetting(String oldOrgId, String newOrgId, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample NotifySetting start {}", newOrgId);
        }
        String notifySettingId = "";
        NotifySetting notifySetting = ticketNotifySettingDao.findByOrgId(oldOrgId);
        if (Objects.isNull(notifySetting)) {
            log.error("[Ticket] CopySample NotifySetting not found");
            return;
        }
        if (Objects.nonNull(notifySetting)) {
            notifySetting.setOrgId(newOrgId);
            //notifySetting.setSample(true);
            notifySetting.setId(ObjectId.next());
            if (isSample) {
                notifySetting.setSample(true);
            }
            if (log.isInfoEnabled()) {
                log.info("[Ticket] CopySample NotifySetting isSample {}", notifySetting.getSample());
            }
            notifySettingId = ticketNotifySettingDao.saveNotifySetting(notifySetting).getId();
        }

        if (log.isInfoEnabled()) {
            log.info("[Ticket] CopySample NotifySetting end {}", notifySettingId);
        }
    }

    /**
     * 复制工单模板
     *
     * @param ticketConfigNew
     * @param ticketConfigOid
     * @author gy.liu
     * @date 2021/8/17
     */
    private TicketTemplateV2 copyTicketTemplate(TicketConfig ticketConfigNew, String ticketConfigOid, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制工单模板开始：param={}", ticketConfigOid);
        }
        TicketTemplateV2 defaultTemplate = templateDao.getDefaultTemplate(ticketConfigNew.getOrgId(), TemplateTypeEnum.TEMPLATE_HANDLE.getIndex());

        if (Objects.nonNull(defaultTemplate)) {
            defaultTemplate.setTicketConfigId(ticketConfigNew.getId());
            defaultTemplate.setUsed(TemplateUsedEnum.TEMPLATE_USED.getIndex());
            defaultTemplate.setRecordFlag(5);
            if (isSample) {
                defaultTemplate.setSample(true);
                if (log.isInfoEnabled()) {
                    log.info("[Ticket] 复制工单模板：param={}", defaultTemplate.getSample());
                }
            }
            templateDao.updateTemplate(defaultTemplate, true);
            ticketConfigNew.setTicketTemplateId(defaultTemplate.getId());
            return defaultTemplate;
        }
        String templateId = "";
        TicketTemplateV2 ticketTemplate = templateDao.getTemplateById(ticketConfigNew.getTicketTemplateId());

        // 复制旧的模板(修改为2.3模板)
        if (Objects.nonNull(ticketTemplate)) {
//            ticketTemplate.setTicketConfigId(ticketConfigNew.getId());
            //ticketTemplate.setSample(true);
            ticketTemplate.setId(ObjectId.next());
            ticketTemplate.setOrgId(ticketConfigNew.getOrgId());
            ticketTemplate.setCreator("系统");
            if (isSample) {
                ticketTemplate.setSample(true);
            }
            templateId = templateDao.insertTemplate(ticketTemplate).getId();
            ticketConfigNew.setTicketTemplateId(templateId);
            return ticketTemplate;
        }
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制工单模板结束：param={}", templateId);
        }
        return null;
    }

    /**
     * 复制提醒
     *
     * @param idMapNodeDTO
     * @param newOrgId
     * @param userId
     * @return void
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/28
     */
    public void copyNotification(IdMapNodeDTO idMapNodeDTO, String newOrgId, String userId, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制提醒：param={}", idMapNodeDTO.getOldId());
        }
        Notification notification = notificationDao.findBySurveyId(idMapNodeDTO.getOldId());
        Notification newNotification = notificationDao.findBySurveyId(idMapNodeDTO.getNewId());
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制提醒：param={},=========old={}", notification, newNotification);
        }
        if (Objects.nonNull(notification)) {
            if (Objects.isNull(newNotification)) {
                notification.setOrgId(newOrgId);
                //notification.setSample(true);
                notification.setId(ObjectId.next());
                notification.setSurveyId(idMapNodeDTO.getNewId());
                Notification.Way way = notification.getWays();
                if (Objects.nonNull(way) && StringUtils.isNotEmpty(userId)) {
                    UserDTO userDTO = ticketBaseUserGrpcService.getUser(userId);
                    if (Objects.nonNull(userDTO)) {
                        String mobile = userDTO.getMobile();
                        List<String> mobiles = new ArrayList<>();
                        if (StringUtils.isNotBlank(mobile) || !"null".equals(mobile)) {
                            mobiles.add(mobile);
                        }
                        way.setMobiles(mobiles);
                        String email = userDTO.getEmail();
                        List<String> emails = new ArrayList<>();
                        if (StringUtils.isNotBlank(email) || !"null".equals(email)) {
                            emails.add(email);
                        }
                        way.setEmails(emails);
                    }
                }
                if (log.isInfoEnabled()) {
                    log.info("[Ticket] 复制提醒：notification={}", isSample);
                }
                if (isSample) {
                    notification.setSample(true);
                    if (log.isInfoEnabled()) {
                        log.info("[Ticket] 复制提醒：notification1={}", notification.getSample());
                    }
                }
                if (log.isInfoEnabled()) {
                    log.info("[Ticket] 复制提醒：notification2={}", notification.getSample());
                }
                notificationDao.saveNotification(notification);
            } else {
                newNotification.setNoDisturb(notification.getNoDisturb());
                newNotification.setWays(notification.getWays());
                newNotification.setRule(notification.getRule());
                if (isSample) {
                    newNotification.setSample(true);
                    if (log.isInfoEnabled()) {
                        log.info("[Ticket] 复制提醒update：notification1={}", newNotification.getSample());
                    }
                } else {
                    newNotification.setSample(notification.getSample());
                    if (log.isInfoEnabled()) {
                        log.info("[Ticket] 复制提醒update：solution={}", newNotification.getSample());
                    }
                }
                notificationDao.updateNotificationBySurveyId(newNotification);
            }
        }
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制提醒：param={}", newNotification.getSample());
        }
    }

    /**
     * 复制通知配置
     *
     * @param ticketConfigNew
     * @author gy.liu
     * @date 2021/8/18
     */
    private void copyNotifyConfig(TicketConfig ticketConfigNew, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制通知配置开始：param={}", ticketConfigNew.getId());
        }
        List<String> notifyConfigIds = new ArrayList<>();
        // 根据id查询通知配置列表
        List<String> ticketNotifyConfigIds = ticketConfigNew.getTicketNotifyConfigIds();
        if (CollUtil.isEmpty(ticketNotifyConfigIds)) {
            log.error("[ticket]-copySample:ticketNotifyConfigIds is empty,ticketId:{}", ticketConfigNew.getId());
            return;
        }
        List<TicketNotifyConfig> ticketNotifyConfigs = ticketNotifyConfigDao.findAllByIds(ticketNotifyConfigIds);
        if (Objects.isNull(ticketNotifyConfigs)) {
            log.error("[Ticket] ticketNotifyConfigs not found");
            return;
        }
        if (!CollectionUtils.isEmpty(ticketNotifyConfigs)) {
            //int index = 0;
            for (TicketNotifyConfig ticketNotifyConfig : ticketNotifyConfigs) {
                // 对象转map
                ticketNotifyConfig.setTicketConfigId(ticketConfigNew.getId());
                // 替换receiver
                replaceReceiver(ticketNotifyConfig);
                // 替换cc
                replaceCc(ticketNotifyConfig);
                // 替换邮箱id
                if (StringUtils.isNotEmpty(ticketConfigNew.getOrgId())) {
                    String smtpId = replaceSmtpId(ticketConfigNew.getOrgId());
                    ticketNotifyConfig.setSmtpId(smtpId);
                    if (log.isInfoEnabled()) {
                        log.info("[Ticket] replaceSmtpId new:{}", ticketNotifyConfig.getSmtpId());
                    }
                }
                // 把通知配置id添加到列表
                ticketNotifyConfig.setOrgId(ticketConfigNew.getOrgId());
                if (isSample) {
                    ticketNotifyConfig.setSample(true);
                }
                ticketNotifyConfig.setId(ObjectId.next());
                String id = ticketNotifyConfigDao.saveTicketNotifyConfig(ticketNotifyConfig).getId();
                // 是否需要转成Obejctid
                notifyConfigIds.add(id);
            }
            // 设置通知配置id到工单配置表
            if (!CollectionUtils.isEmpty(notifyConfigIds)) {
                ticketConfigNew.setTicketNotifyConfigIds(notifyConfigIds);
            }
        }
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制通知配置结束：param={}", JSONObject.toJSONString(ticketNotifyConfigIds));
        }
    }

    /**
     * 根据机构号获取邮箱id
     *
     * @param newOrgId
     * @return String
     * @author gy.liu
     * @date 2021/9/7
     */
    public String replaceSmtpId(String newOrgId) {
        if (StringUtils.isNotEmpty(newOrgId)) {
            List<SmtpDTO> smtpDTOS = ticketBaseUserGrpcService.listSmtpByOrgId(newOrgId, true);
            if (!CollectionUtils.isEmpty(smtpDTOS)) {
                if (log.isInfoEnabled()) {
                    log.info("[Ticket] replaceSmtpId：param={}", smtpDTOS.get(0).getId());
                }
                return smtpDTOS.get(0).getId();
            }
        }
        return "";
    }

    /**
     * 复制工单流程
     *
     * @param ticketConfigNew
     * @param ticketConfigOld
     * @author gy.liu
     * @date 2021/8/18
     */
    private void copyTicketFlow(TicketConfig ticketConfigNew, String ticketConfigOld, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制工单流程开始：param={}", ticketConfigNew.getId());
        }
        List<String> ticketFlowIds = new ArrayList<>();
        List<TicketFlow> ticketFlows = ticketFlowDao.findByConfigId(ticketConfigOld);
        if (Objects.isNull(ticketFlows)) {
            log.error("[Ticket] ticketFlows not found");
            return;
        }
        if (!CollectionUtils.isEmpty(ticketFlows)) {
            for (TicketFlow ticketFlow : ticketFlows) {
                ticketFlow.setOrgId(ticketConfigNew.getOrgId());
                ticketFlow.setTicketConfigId(ticketConfigNew.getId());
                // 替换rpc返回的流程配置信息到新的工单流程
                replaceFlowConfig(ticketFlow);
                if (log.isInfoEnabled()) {
                    log.info("[Ticket] 复制工单流程配置：param={}", ticketFlow.getFollowConfig());
                }
                // 替换rpc返回的审计配置信息到新的工单流程
                replaceAuditConfig(ticketFlow);
                // 替换rpc字段
                String[] fields = {"userId", "alertRuleIds", "customRuleIds"};
                String userId = rpcModelIdMap.get(ticketFlow.getUserId());
                ticketFlow.setUserId(userId);
                // 保存工单流程信息
                ticketFlow.setId(ObjectId.next());
                ticketFlow.setOrgId(ticketConfigNew.getOrgId());
                if (isSample) {
                    ticketFlow.setSample(true);
                }
                ticketFlow = ticketFlowDao.saveTicketFlow(ticketFlow);
                ticketFlowIds.add(ticketFlow.getId());
            }
            ticketConfigNew.setTicketFlowIds(ticketFlowIds);
        }
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制工单流程结束：param={}", ticketConfigNew.getTicketFlowIds());
        }
    }


    /**
     * 工单复制
     *
     * @param ticketConfigNew
     * @param configId
     * @param ticketIdMap
     * @return void
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/19
     */
    private void copyTicket(TicketConfig ticketConfigNew, String configId, Map<String, String> ticketIdMap, TicketTemplateV2 template, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[ticket] 复制工单开始：param={}", ticketConfigNew.getId());
        }
        // 根据configid查询工单信息
        List<Ticket> tickets = ticketDao.findTicketsByConfigId(configId);
        if (log.isInfoEnabled()) {
            log.info("[ticket] 复制工单中间：param={}", JSONObject.toJSONString(tickets));
        }
        // 将新旧id放入map key是旧的id,value是新的id
        if (CollectionUtils.isEmpty(tickets)) {
            log.error("[ticket] 复制工单开始：not found ticket,ticketConfigId:{}", configId);
            return;
        }
        // 调用python查询问卷的信息 获取问卷项目。
        Map<String, String> groupInfo = new HashMap<>(16);
        if (StringUtils.isNotEmpty(ticketConfigNew.getSurveyId())) {
            SurveyProjectDTO surveyProject = cacheProjectClient.getSurveyProject(ticketConfigNew.getSurveyId());
            groupInfo.put("surveyCode", surveyProject.getCode());
        }
        GroupDTO rootGroup = ticketUserGrpcService.getRootGroupByOrgId(ticketConfigNew.getOrgId());
        String groupId = "";
        String groupName = "";
        String userGroupCode = "";
        String regionName = "";
        if (Validator.isNotNull(rootGroup)) {
            groupId = rootGroup.getId();
            groupName = rootGroup.getTitle();
        }
        // 获取用户组code。发送工单mq使用。
        if (Validator.isNotEmpty(groupId)) {
            GroupDTO groupDTO = ticketBaseUserGrpcService.getGroup(groupId);
            if (Validator.isNotNull(groupDTO)) {
                userGroupCode = groupDTO.getCode();
                regionName = groupDTO.getTitle();
            }
        }
        groupInfo.put("groupId", groupId);
        groupInfo.put("groupName", groupName);
        groupInfo.put("userGroupCode", userGroupCode);
        groupInfo.put("regionName", regionName);
        for (Ticket ticket : tickets) {
            if (log.isInfoEnabled()) {
                log.info("[ticket] 复制工单begin：param={}", ticket.getId());
            }

            // 缓存copySample中的工单编号，解决工单编号重复情况
            ticketUtil.cacheTicketNoForCopySample(ticket, ticketConfigNew.getOrgId());
            if (log.isInfoEnabled()) {
                log.info("[ticket] 复制工单ticketNo：param={}", ticket.getTicketNo());
            }
            String ticketId = ticket.getId();
            ticket.setOrgId(ticketConfigNew.getOrgId());
            // 处理模板
            if (Objects.nonNull(template)) {
                ticket.setTicketTemplateV2(template);
                ticket.setHandleTemplateId(template.getId());
            }
            // 替换grpc字段 确认问卷id是否替换
            if (!StringUtils.isEmpty(ticket.getSurveyId())) {
                String surveyId = rpcModelIdMap.get(ticket.getSurveyId());
                ticket.setSurveyId(surveyId);
            }
            ticket.setMemberId("");
            if (!StringUtils.isEmpty(ticket.getRegion())) {
                String region = rpcModelIdMap.get(ticket.getRegion());
                ticket.setRegion(region);
            }
            // 替换用户id
            replaceUserId(ticket);
            // 替换角色
            replaceRoleId(ticket);
            //别的字段是否需要转换
            ticket.setTicketConfigId(ticketConfigNew.getId());
            // 替换答卷编号
            if (Objects.nonNull(ticket.getResId())) {
    /*            if (log.isInfoEnabled()) {
                    log.info("[Ticket] copyTicket res={}", ticket.getResId());
                }*/
                if (seqMap.containsKey(String.valueOf(ticket.getResId()))) {
                    String seq = seqMap.get(String.valueOf(ticket.getResId()));
                    if (log.isInfoEnabled()) {
                        log.info("[Ticket] copyTicket resMid={}", seq);
                    }
                    ticket.setResId(Long.valueOf(seq));
                    if (log.isInfoEnabled()) {
                        log.info("[Ticket] copyTicket resEnd={}", ticket.getResId());
                    }
                }
            }
            // ticketFlow处理 目前用的旧的
            //List<String> ticketFlowIds = new ArrayList<>();
            // id是否要改 设置工单流程信息
            TicketFlow ticketFlowNew = chooseTicketFlow(ticketConfigNew.getId(), ticketConfigNew.getTicketFlowIds());
            if (Objects.nonNull(ticketFlowNew)) {
                ticket.setTicketFlow(ticketFlowNew);
            }
            // 预警规则替换
   /*     if(!CollectionUtils.isEmpty(ticket.getAlertRuleIds())){
               List<TicketRule> ticketRules = ticketRuleDao.listByIds(ticket.getAlertRuleIds(),configId);

        }*/
            // 预警记录替换
            if (StringUtils.isNotEmpty(ticket.getAlertRecordId())) {
                String recordId = copyRecord(ticketConfigNew, ticket.getAlertRecordId(), isSample);
                ticket.setAlertRecordId(recordId);
            }
            ticket.setId(ObjectId.next());
            // 更新模板字段,config是对的
            if (Objects.nonNull(ticketConfigNew.getTemplateDetailFields())) {
                ticket.setTemplateDetailFields(ticketConfigNew.getTemplateDetailFields());
            }
            // 更新记录id
            if (isSample) {
                ticket.setSample(true);
                if (log.isInfoEnabled()) {
                    log.info("[ticket] 复制工单end：ticket1={}", ticket.getSample());
                }
            }
            if (log.isInfoEnabled()) {
                log.info("[ticket] 复制工单end：ticket2={}", ticket.getSample());
            }
            ticketDao.saveTicketCopy(ticket);
            // 发送工单创建MQ给BI
            //ticketMqProductUtil.publishTicketCreateMQ(ticket, groupInfo);
            ticketIdMap.put(ticketId, ticket.getId());
            log.info("[ticket] 工单id集合：param={},oldId={}", ticket.getId(), ticketId);
            List<TicketRecord> ticketRecords = ticketRecordDao.listByTicketId(ticketId);
            // 复制工单记录
            ArrayList<String> ticketRecordIds = new ArrayList<>();
            if (CollUtil.isNotEmpty(ticketRecords)) {
                List<TicketRecord> sortedTickets = ticketRecords.stream().sorted(Comparator.comparing(BaseEntity::getCreatedDate).reversed()).collect(Collectors.toList());
                boolean exist = false;
                for (TicketRecord ticketRecord : sortedTickets) {
                    copyTicketRecord(ticketRecord, ticket, ticketConfigNew.getOrgId(), isSample);
                    // 发送工单日志MQ
                    if (sortedTickets.size() == 1) {
                        // 如果只有一条工单日志，那么使用工单的状态作为工单日志中的工单状态
                        ticketRecord.setTicketStatus(ticket.getStatus());
                    }
                    // 相同的跟进日志只发送一次消息
                    if (TicketStatusEnum.FOLLOWING.getIndex().equals(ticketRecord.getTicketStatus()) && exist) {
                        continue;
                    }
                    if (TicketEventEnum.FOLLOW_OVERDUE.getIndex().equals(ticketRecord.getEvent())) {
                        // 跟进逾期日志不重刷
                        continue;
                    }
                    if (TicketEventEnum.FOLLOW_OVERDUE_REMIND.getIndex().equals(ticketRecord.getEvent())) {
                        // 跟进逾期提醒日志不重刷
                        continue;
                    }
                    if (TicketEventEnum.AUDIT_OVERDUE_REMIND.getIndex().equals(ticketRecord.getEvent())) {
                        // 审核逾期提醒日志不重刷
                        continue;
                    }
                    if (TicketEventEnum.AUDIT_OVERDUE.getIndex().equals(ticketRecord.getEvent())) {
                        // 审核逾期日志不重刷
                        continue;
                    }
                    if (TicketStatusEnum.FOLLOWING.getIndex().equals(ticketRecord.getTicketStatus())) {
                        // 记录已经发送过跟进日志的工单id
                        exist = true;
                    }
                    String surveyCode = groupInfo.getOrDefault("surveyCode", "");
                    ticketMessageSendService.publishTicketRecordCreateMq(ticket, ticketRecord, userGroupCode, surveyCode, regionName);

                    ticketRecordIds.add(ticketRecord.getId());
                }
            }
            ticket.setTicketRecordIds(ticketRecordIds);
            if (log.isInfoEnabled()) {
                log.info("[ticket] 复制工单end：ticket={}", isSample);
            }

            ticketDao.updateTicketRecordId(ticket);
            // 发送工单创建MQ给BI
            ticketMessageSendService.publishTicketCreateMQ(ticket, groupInfo);
            if (log.isInfoEnabled()) {
                log.info("[ticket] 复制工单end：param={}", ticket.getId());
            }

        }
        if (log.isInfoEnabled()) {
            log.info("[ticket] 复制工单结束");
        }
    }

    private void replaceRoleId(Ticket ticket) {
        if (!StringUtils.isEmpty(ticket.getFollowRoleId())) {
            String roleId = rpcModelIdMap.get(ticket.getFollowRoleId());
            if (StringUtils.isNotEmpty(roleId)) {
                ticket.setFollowRoleId(roleId);
                log.info("[Ticket] replaceRoleId res={}", roleId);
            }
        }
        if (!StringUtils.isEmpty(ticket.getAuditRoleId())) {
            String roleId = rpcModelIdMap.get(ticket.getAuditRoleId());
            if (StringUtils.isNotEmpty(roleId)) {
                ticket.setAuditRoleId(roleId);
                log.info("[Ticket] replaceRoleIdA res={}", roleId);
            }
        }
    }

    /**
     * 替换用户id
     *
     * @param ticket
     * @return void
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/28
     */
    private void replaceUserId(Ticket ticket) {
        List<String> userIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(ticket.getCurFollowUserId())) {
            for (String userId : ticket.getCurFollowUserId()) {
                String userIdNew = rpcModelIdMap.get(userId);
                if (StringUtils.isNotEmpty(userIdNew)) {
                    userIds.add(userIdNew);
                }
            }
            if (!CollectionUtils.isEmpty(userIds)) {
                ticket.setCurFollowUserId(userIds);
                log.info("[Ticket] replaceUserId res={}", ticket.getCurFollowUserId());
            }
        }
        if (!CollectionUtils.isEmpty(ticket.getAuditUserIds())) {
            for (String userId : ticket.getAuditUserIds()) {
                String userIdNew = rpcModelIdMap.get(userId);
                if (StringUtils.isNotEmpty(userIdNew)) {
                    userIds.add(userIdNew);
                }
            }
            if (!CollectionUtils.isEmpty(userIds)) {
                ticket.setAuditUserIds(userIds);
            }
        }
        if (!CollectionUtils.isEmpty(ticket.getFollowUserIds())) {
            for (String userId : ticket.getFollowUserIds()) {
                String userIdNew = rpcModelIdMap.get(userId);
                if (StringUtils.isNotEmpty(userIdNew)) {
                    userIds.add(userIdNew);
                }
            }
            if (!CollectionUtils.isEmpty(userIds)) {
                ticket.setFollowUserIds(userIds);
                log.info("[Ticket] replaceUserId foll={}", ticket.getFollowUserIds());
            }
        }
        if (!StringUtils.isEmpty(ticket.getFollowRoleId())) {
            String userIdNew = rpcModelIdMap.get(ticket.getFollowRoleId());
            if (StringUtils.isNotEmpty(userIdNew)) {
                ticket.setFollowRoleId(userIdNew);
            }
        }
        // add creator
        if (StringUtils.isNotEmpty(ticket.getCreatedId())) {
            String userIdNew = rpcModelIdMap.get(ticket.getCreatedId());
            if (StringUtils.isNotEmpty(userIdNew)) {
                ticket.setCreatedId(userIdNew);
            }
        }
        // add update
        if (StringUtils.isNotEmpty(ticket.getUpdatedId())) {
            String userIdNew = rpcModelIdMap.get(ticket.getUpdatedId());
            if (StringUtils.isNotEmpty(userIdNew)) {
                ticket.setUpdatedId(userIdNew);
            }
        }
    }

    /**
     * 获取配置中的工单流程
     * 选择使用哪个工单流程.
     * 1. 从已启用的流程中, 按照优先级从高到低匹配
     * 2. 使用第一个满足工单流程条件设置的
     *
     * @param ticketConfigId 工单配置id
     * @param ticketFlowIds  流程ids
     * @return String
     * @author jy.zhao
     * @date 2021/8/17 21:22
     **/
    private TicketFlow chooseTicketFlow(String ticketConfigId, List<String> ticketFlowIds) {
        if (log.isInfoEnabled()) {
            log.info("[ticket] 获取工单流程");
        }
        TicketFlow matchedTicketFlow = null;

        List<TicketFlow> ticketFlows;
        if (CollUtil.isEmpty(ticketFlowIds)) {
            // 1. 从已启用的流程中, 按照优先级从高到低匹配
            ticketFlows = ticketFlowDao.findTicketFlowByStatus(ticketConfigId, TicketFlowStatusEnum.ENABLED.getIndex());
        } else {
            ticketFlows = ticketFlowDao.findTicketFlowById(ticketConfigId, ticketFlowIds);
        }
        if (log.isInfoEnabled()) {
            log.info("[ticket] 工单配置:{} 流程数据:{}", ticketConfigId, ticketFlows.size());
        }
        for (TicketFlow ticketFlow : ticketFlows) {
            // 无条件所有工单执行此流程，目前前端MatchCondition只会传1
            if (ticketFlow.getMatchCondition() == TicketFlowMatchConditionEnum.UNCONDITIONAL.getIndex()) {
                matchedTicketFlow = ticketFlow;
                break;
            }
        }
        if (log.isInfoEnabled()) {
            log.info("[ticket] 匹配到的工单流程:{} 工单流程无条件执行", matchedTicketFlow);
        }

        return matchedTicketFlow;
    }


    /**
     * 复制工单记录
     *
     * @param ticketRecord
     * @param ticket
     * @param orgId
     * @param orgId
     * @return void
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/19
     */
    private void copyTicketRecord(TicketRecord ticketRecord, Ticket ticket, String orgId, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[ticket] 复制工单记录开始：param={}", ticket.getId());
        }
        ticketRecord.setTicketId(ticket.getId());
        String[] rpcFields = {"userId", "roleId", "region", "surveyId"};
        String userId = "";
        if (!StringUtils.isEmpty(ticketRecord.getUserId())) {
            userId = rpcModelIdMap.get(ticketRecord.getUserId());
        }
        String roleId = "";
        if (!StringUtils.isEmpty(ticketRecord.getRoleId())) {
            roleId = rpcModelIdMap.get(ticketRecord.getRoleId());
        }
        String region = "";
        if (!StringUtils.isEmpty(ticketRecord.getRegion())) {
            region = rpcModelIdMap.get(ticketRecord.getRegion());
        }
        String surveyId = "";
        if (!StringUtils.isEmpty(ticketRecord.getSurveyId())) {
            surveyId = rpcModelIdMap.get(ticketRecord.getSurveyId());
        }
        ticketRecord.setUserId(userId);
        ticketRecord.setRoleId(roleId);
        ticketRecord.setRegion(region);
        ticketRecord.setSurveyId(surveyId);
        ticketRecord.setId(ObjectId.next());
        // ticketRecord.setSample(true);
        if (isSample) {
            ticketRecord.setSample(true);
        }
        ticketRecord.setOrgId(orgId);
        ticketRecordDao.saveTicketRecord(ticketRecord);

        if (log.isInfoEnabled()) {
            log.info("[ticket] 复制工单记录结束：param={}", ticketRecord.getId());
        }
    }


    /**
     * 复制工单规则
     *
     * @param ticketConfigNew
     * @param existTicketRuleId
     * @author gy.liu
     * @date 2021/8/18
     */
    private String copyTicketRule(String ticketRuleId, TicketConfig ticketConfigNew, String existTicketRuleId, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制工单规则开始：param={}", ticketConfigNew.getId());
        }
        TicketRule ticketRule;
        if (StringUtils.isNotEmpty(existTicketRuleId)) {
            ticketRule = ticketRuleDao.findById(existTicketRuleId);
        } else {
            ticketRule = ticketRuleDao.findById(ticketRuleId);
        }
        if (log.isInfoEnabled()) {
            log.info("[ticket]: 复制工单规则起飞,触发规则ticketRule:{},行动规则id,ticketConfigId:{},oleTicetRuleId:{}", ticketRule, ticketConfigNew.getId(), ticketRuleId);
        }
        // 旧的工单规则转对象
        ticketRule.setTicketConfigId(ticketConfigNew.getId());
        String[] rpcFields = {"surveyId"};
        String surveyId = "";
        if (!StringUtils.isEmpty(ticketRule.getSurveyId())) {
            surveyId = rpcModelIdMap.get(ticketRule.getSurveyId());
        }
        ticketRule.setSurveyId(surveyId);
        ticketRule.setId(ObjectId.next());
    /*    if (StringUtils.isNotEmpty(existTicketRuleId)) {
            ticketRule.setId(existTicketRuleId);
        }*/
        if (isSample) {
            ticketRule.setSample(true);
        }
        ticketRule = ticketRuleDao.saveTicketRule(ticketRule);
        ticketConfigNew.setTicketRuleId(ticketRule.getId());
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制工单规则开始：param={}", ticketConfigNew.getId());
        }
        return ticketRule.getId();
    }

    /**
     * 复制状态规则列表
     *
     * @param ticketConfigNew
     * @author gy.liu
     * @date 2021/8/18
     */
    private void copyStatusRuleList(String ticketRuleId, TicketConfig ticketConfigNew, Boolean isSample) {
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制状态规则列表开始：param={}", ticketConfigNew.getId());
        }
        List<JSONObject> newIdList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(ticketConfigNew.getStatusRuleList())) {
            List<JSONObject> statusRuleList = ticketConfigNew.getStatusRuleList();
            if (CollUtil.isNotEmpty(statusRuleList)) {
                for (JSONObject statusRuleMap : statusRuleList) {
                    JSONObject jsonObject = new JSONObject();
                    // 遍历列表保存工单规则
                    if (!CollectionUtils.isEmpty(statusRuleMap.keySet())) {
                        for (String statusKey : statusRuleMap.keySet()) {
                            String newRuleId = copyTicketRule(ticketRuleId, ticketConfigNew, statusKey, isSample);
                            if (StringUtils.isNotEmpty(newRuleId)) {
                                jsonObject.put(newRuleId, statusRuleMap.getString(statusKey));
                            }
                        }
                        if (!jsonObject.isEmpty()) {
                            newIdList.add(jsonObject);
                        }
                    }
                }
            }
            // 更新规则列表到工单配置
            if (!CollectionUtils.isEmpty(newIdList)) {
                ticketConfigNew.setStatusRuleList(newIdList);
            }
        }
        if (log.isInfoEnabled()) {
            log.info("[Ticket] 复制状态规则列表开始：param={}", ticketConfigNew.getId());
        }
    }

    /**
     * 复制工单详情字段
     *
     * @param ticketConfigNew
     * @author gy.liu
     * @date 2021/8/18
     */
    private void copyTicketDetailFields(TicketConfig ticketConfigNew) {
        // grpc获取问卷信息
        List<ColumnDTO> newFields = ticketSurveyGrpcService.getColumnsBySurveyId(ticketConfigNew.getSurveyId());
        if (CollUtil.isEmpty(newFields)) {
            log.error("[Ticket] copyTicketDetailFields getSurvey failed");
            return;
        }
        if (log.isInfoEnabled()) {
            log.info("[Ticket] copyTicketDetailFields：newFields={}", newFields);
        }
        List<Ticket.TemplateDetailField> fields = ticketConfigNew.getTemplateDetailFields();
        if (CollUtil.isNotEmpty(fields)) {
            // 遍历旧的字段列表
            for (Ticket.TemplateDetailField field : fields) {
                if (StringUtils.isNotEmpty(field.getSourceId())) {
                    ColumnDTO oldField = ticketBaseSurveyGrpcService.getColumn(field.getSourceId());
                    log.error("[Ticket] copyTicketDetailFields getSurvey {}", oldField);
                    if (Objects.isNull(oldField)) {
                        continue;
                    }
                    String oldFieldCol = oldField.getCol();
                    for (ColumnDTO newColumn : newFields) {
                        if (oldFieldCol.equals(newColumn.getCol())) {
                            field.setSourceId(newColumn.getId());
                            break;
                        }
                    }
                }
            }
            if (log.isInfoEnabled()) {
                log.info("[Ticket] copyTicketDetailFields:param={}", fields);
            }
            // 设置详情字段
            ticketConfigNew.setTemplateDetailFields(fields);
        }
    }

    /**
     * 流程配置信息替换
     *
     * @param ticketFlow
     * @author gy.liu
     * @date 2021/8/18
     */
    private void replaceFlowConfig(TicketFlow ticketFlow) {
        // 替换rpc返回的流程配置信息到新的工单流程
        if (!CollectionUtils.isEmpty(ticketFlow.getFollowConfig())) {
            List<TicketFlow.FollowConfig> followConfigs = new ArrayList<>();
            for (TicketFlow.FollowConfig followConfig : ticketFlow.getFollowConfig()) {
                if (StringUtils.isNotEmpty(followConfig.getRegion())) {
                    followConfig.setRegion(rpcModelIdMap.get(followConfig.getRegion()));
                }
                if (StringUtils.isNotEmpty(followConfig.getRoleId())) {
                    followConfig.setRoleId(rpcModelIdMap.get(followConfig.getRoleId()));
                }
                if (StringUtils.isNotEmpty(followConfig.getFollowerId())) {
                    followConfig.setFollowerId(rpcModelIdMap.get(followConfig.getFollowerId()));
                    if (log.isInfoEnabled()) {
                        log.info("[Ticket] replaceFlowConfig={},flowId:{}", followConfig.getFollowerId(), ticketFlow.getId());
                    }
                }
                if (StringUtils.isNotEmpty(followConfig.getFollowerEmail())) {
                    followConfig.setFollowerEmail(rpcModelIdMap.get(followConfig.getFollowerEmail()));
                }
                if (StringUtils.isNotEmpty(followConfig.getFollowerName())) {
                    followConfig.setFollowerName(rpcModelIdMap.get(followConfig.getFollowerName()));
                }
                // todo: options处理，酒店行业无options
                followConfigs.add(followConfig);
            }
            // 设置工单流程的流程配置信息
            ticketFlow.setFollowConfig(followConfigs);
        }
    }

    /**
     * 审计配置替换
     *
     * @param ticketFlow
     * @author gy.liu
     * @date 2021/8/18
     */
    private void replaceAuditConfig(TicketFlow ticketFlow) {
        // 替换rpc返回的审计配置信息到新的工单流程
        if (!CollectionUtils.isEmpty(ticketFlow.getAuditConfig())) {
            List<TicketFlow.FollowConfig> followConfigs = new ArrayList<>();
            for (TicketFlow.FollowConfig followConfig : ticketFlow.getAuditConfig()) {
                if (StringUtils.isNotEmpty(followConfig.getRegion())) {
                    followConfig.setRegion(rpcModelIdMap.get(followConfig.getRegion()));
                }
                if (StringUtils.isNotEmpty(followConfig.getRoleId())) {
                    followConfig.setRoleId(rpcModelIdMap.get(followConfig.getRoleId()));
                }
                if (StringUtils.isNotEmpty(followConfig.getFollowerId())) {
                    followConfig.setFollowerId(rpcModelIdMap.get(followConfig.getFollowerId()));
                }
                followConfigs.add(followConfig);
            }
            // 设置工单流程的审计配置信息
            ticketFlow.setAuditConfig(followConfigs);
        }
    }

    /**
     * 替换rpc字段
     *
     * @param rpcFields
     * @param newTicketConfigMap
     * @author gy.liu
     * @date 2021/8/16
     */
    private void repalceRpcFields(String[] rpcFields, Map<String, Object> newTicketConfigMap) {
        if (!CollectionUtils.isEmpty(Arrays.asList(rpcFields))) {
            for (String rpcField : rpcFields) {
                Object rpcValue = newTicketConfigMap.get(rpcField);
                // 获取新对象map,用rpc返回的值更新对应的值,根据不同类型转化(字符串,对象id,列表)
                if (Objects.nonNull(rpcValue)) {
                    if (rpcValue instanceof String) {
                        String newId = rpcModelIdMap.get(rpcValue);
                        if (StringUtils.isNotEmpty(newId)) {
                            newTicketConfigMap.put(rpcField, newId);
                        }
                    } else if (rpcValue instanceof List) {
                        // 列表类型需要继续循环
                        List<String> rpcValues = (List<String>) rpcValue;
                        List<Object> newChildList = new ArrayList<>();
                        if (!CollectionUtils.isEmpty(newChildList)) {
                            for (String newId : rpcValues) {
                                String newChildId = rpcModelIdMap.get(newId);
                                if (StringUtils.isNotEmpty(newChildId)) {
                                    newChildList.add(newChildId);
                                }
                            }
                            if (!CollectionUtils.isEmpty(newChildList)) {
                                newTicketConfigMap.put(rpcField, newChildList);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * receiver的替换
     *
     * @param ticketNotifyConfig
     * @author gy.liu
     * @date 2021/8/17
     */
    private void replaceReceiver(TicketNotifyConfig ticketNotifyConfig) {
        List<TicketNotifyConfig.ReceiveUser> newReceiver = new ArrayList<>();
        if (!CollectionUtils.isEmpty(ticketNotifyConfig.getReceiverList())) {
            // receiver是RoleRegion的rpc返回替换
            // 按照python的代码应该有两种格式map或者列表
            // map的处理
            for (TicketNotifyConfig.ReceiveUser roleRegion : ticketNotifyConfig.getReceiverList()) {
                TicketNotifyConfig.ReceiveUser newRegion = new TicketNotifyConfig.ReceiveUser();
                if (StringUtils.isNotEmpty(roleRegion.getRegion())) {
                    newRegion.setRegion(rpcModelIdMap.get(roleRegion.getRegion()));
                }
                if (StringUtils.isNotEmpty(roleRegion.getRoleId())) {
                    newRegion.setRoleId(rpcModelIdMap.get(roleRegion.getRoleId()));
                }
                if (StringUtils.isNotEmpty(roleRegion.getId())) {
                    newRegion.setId(rpcModelIdMap.get(roleRegion.getId()));
                }
                if (StringUtils.isNotEmpty(newRegion.getId())) {
                    UserDTO userDTO = ticketBaseUserGrpcService.getUser(newRegion.getId());
                    if (Objects.nonNull(newRegion) && Objects.nonNull(userDTO)) {
                        if (log.isInfoEnabled()) {
                            log.info("[Ticket] replaceReceiver begin：param={}", userDTO.getEmail());
                        }
                        newRegion.setMobile(userDTO.getMobile());
                        newRegion.setEmail(userDTO.getEmail());
                        newRegion.setUserName(userDTO.getUserName());
                        if (log.isInfoEnabled()) {
                            log.info("[Ticket] replaceReceiver：param={}", newRegion.getMobile());
                        }
                    }
                }
                newReceiver.add(newRegion);

            }
            // 保存receiver到map
//            if (!CollectionUtils.isEmpty(newReceiver)) {
            ticketNotifyConfig.setReceiverList(newReceiver);
//            }
        }
    }

    /**
     * cclist替换
     *
     * @param ticketNotifyConfig
     * @author gy.liu
     * @date 2021/8/18
     */
    private void replaceCc(TicketNotifyConfig ticketNotifyConfig) {
        List<TicketNotifyConfig.RoleRegion> newCc = new ArrayList<>();
        if (!CollectionUtils.isEmpty(ticketNotifyConfig.getCcList())) {
            // 把旧的对象字段用rpc返回的替换
            for (TicketNotifyConfig.RoleRegion roleRegion : ticketNotifyConfig.getCcList()) {
                TicketNotifyConfig.RoleRegion newRegion = new TicketNotifyConfig.RoleRegion();
                if (StringUtils.isNotEmpty(roleRegion.getRegion())) {
                    newRegion.setRegion(rpcModelIdMap.get(roleRegion.getRegion()));
                }
                if (StringUtils.isNotEmpty(roleRegion.getRoleId())) {
                    newRegion.setRoleId(rpcModelIdMap.get(roleRegion.getRoleId()));
                }
                if (StringUtils.isNotEmpty(roleRegion.getCcId())) {
                    newRegion.setCcId(rpcModelIdMap.get(roleRegion.getCcId()));
                }
                if (StringUtils.isNotEmpty(roleRegion.getId())) {
                    newRegion.setId(rpcModelIdMap.get(roleRegion.getId()));
                }
                if (Objects.nonNull(roleRegion.getCcFilter())) {
                    newRegion.setCcFilter(roleRegion.getCcFilter());
                    if (log.isInfoEnabled()) {
                        log.info("[Ticket] setCcFilter：param={}", newRegion.getCcFilter());
                    }
                }
                if (Objects.nonNull(newRegion)) {
                    if (StringUtils.isNotEmpty(newRegion.getId())) {
                        UserDTO userDTO = ticketBaseUserGrpcService.getUser(newRegion.getId());
                        if (Objects.nonNull(newRegion) && Objects.nonNull(userDTO)) {
                            if (log.isInfoEnabled()) {
                                log.info("[Ticket] replaceCc begin：param={}", userDTO.getEmail());
                            }
                            newRegion.setMobile(userDTO.getMobile());
                            newRegion.setEmail(userDTO.getEmail());
                            newRegion.setUserName(userDTO.getUserName());
                            if (log.isInfoEnabled()) {
                                log.info("[Ticket] replaceCc：param={}", newRegion.getMobile());
                            }
                        }
                    }
                }
                // 是否需要判断region和roleId和ccId同时存在
                newCc.add(newRegion);
            }
            // 保存ccList
//            if (!CollectionUtils.isEmpty(newCc)) {
            ticketNotifyConfig.setCcList(newCc);
//            }
        }
    }

}
